#define _CRT_SECURE_NO_WARNINGS
//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//using namespace std;
//
//int main()
//{
//	int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
//	int n, m;
//	cin >> n >> m;
//	vector<vector<int>> graph(n);
//	vector<bool> visited1(n,false), visited2(n, false);
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		graph[t1].push_back(t2);
//		graph[t2].push_back(t1);
//	}
//	for (int i = 0; i < n; i++)
//	{
//		if (graph[i].size() > 0)
//			sort(graph[i].begin(), graph[i].end());
//	}
//	vector<vector<int>> v1,v2;
//	function<void(int)> dfs = [&](int i)
//	{
//		visited1[i]= true;
//		v1.back().push_back(i);
//		for (auto& e : graph[i])
//		{
//			if (visited1[e] == false)
//				dfs(e);
//		}
//	};
//	auto bfs = [&](int i)
//	{
//		queue<int> q;
//		q.push(i);
//		visited2[i] = true;
//		v2.back().push_back(i);
//		while (!q.empty())
//		{
//			auto tmp = q.front();
//			q.pop();
//			for (auto& e : graph[tmp])
//			{
//				if (visited2[e] == false)
//				{
//					q.push(e);
//					visited2[e] = true;
//					v2.back().push_back(e);
//				}
//			}
//		}
//	};
//	for (int i = 0; i < n; i++)
//	{
//		if (visited1[i] == false)
//		{
//			v1.push_back({});
//			dfs(i);
//		}
//	}
//	for (int i = 0; i < n; i++)
//	{
//		if (visited2[i] == false)
//		{
//			v2.push_back({});
//			bfs(i);
//		}
//	}
//	for (auto& v : v1)
//	{
//		cout << "{ ";
//		for (auto& e : v)
//			cout << e << " ";
//		cout << "}";
//		cout << endl;
//	}
//	for (auto& v : v2)
//	{
//		cout << "{ ";
//		for (auto& e : v)
//			cout << e << " ";
//		cout << "}";
//		cout << endl;
//	}
//	return 0;
//}

//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//using namespace std;
//
//int main()
//{
//	int n, m;
//	cin >> n >> m;
//	vector<vector<int>> graph(n);
//	vector<bool> visited1(n, false), visited2(n, false);
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		graph[t1].push_back(t2);
//	}
//	for (int i = 0; i < n; i++)
//	{
//		if (graph[i].size() > 0)
//			sort(graph[i].begin(), graph[i].end());
//	}
//	vector<int> v1;
//	function<void(int)> dfs = [&](int i)
//	{
//		visited1[i] = true;
//		v1.push_back(i);
//		for (auto& e : graph[i])
//		{
//			if (visited1[e] == false)
//				dfs(e);
//		}
//	};
//	for (int i = 0; i < n; i++)
//	{
//		if (visited1[i] == false)
//			dfs(i);
//	}
//	for (auto& e : v1)
//		cout << e << " ";
//	return 0;
//}

//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//#include<numeric>
//using namespace std;
//
//class Djset
//{
//public:
//	vector<int> parent;
//	Djset(int n)
//	{
//		parent.resize(n);
//		iota(parent.begin(), parent.end(),0);
//	}
//	int find(int x)
//	{
//		if (x != parent[x])
//			parent[x] = find(parent[x]);
//		return parent[x];
//	}
//	void merge(int x, int y)
//	{
//		int fx = find(x),fy = find(y);
//		if (fx == fy)
//			return;
//		parent[fy] = fx;
//	}
//};
//vector<vector<int>> graph;
//int main()
//{
//	int n, m;
//	cin >> n >> m;
//	graph.resize(n);
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		graph[t1].push_back(t2);
//	}
//	int t1, t2;
//	cin >> t1 >> t2;
//	Djset ds(n);
//	for (int i = 0; i < n; i++)
//	{
//		for (auto& e : graph[i])
//		{
//			if (ds.find(e) != ds.find(i))
//				ds.merge(e, i);
//		}
//	}
//	if (ds.find(t1) == ds.find(t2))
//		cout << "There is a path between "<<t1<<" and "<<t2<<".";
//	else
//		cout << "There is no path between " << t1 << " and " << t2 << ".";
//	return 0;
//}

//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//#include<numeric>
//using namespace std;
//class Djset
//{
//public:
//	vector<int> parent;
//	int count;
//	Djset(int n)
//		:count(n)
//	{
//		parent.resize(n);
//		iota(parent.begin(), parent.end(), 0);
//	}
//	int find(int x)
//	{
//		if (x != parent[x])
//			parent[x] = find(parent[x]);
//		return parent[x];
//	}
//	void merge(int x, int y)
//	{
//		int fx = find(x), fy = find(y);
//		if (fx == fy)
//			return;
//		parent[fy] = fx;
//		count--;
//	}
//};
//vector<vector<int>> graph;
//int main()
//{
//	int n, m;
//	cin >> n >> m;
//	graph.resize(n + 1);
//	vector<int> count(n + 1);
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		graph[t1].push_back(t2);
//		count[t1]++;
//		count[t2]++;
//	}
//	int tmp = 0;
//	for (int i = 1; i <= n; i++)
//	{
//		if (count[i] % 2)
//			tmp++;
//	}
//	if (tmp == 0 || tmp == 2)
//	{
//		Djset ds(n + 1);
//		for (int i = 1; i <= n; i++)
//		{
//			if (graph[i].size() == 0)
//				continue;
//			for (auto& e : graph[i])
//			{
//				if (ds.find(e) != ds.find(i))
//					ds.merge(e, i);
//			}
//		}
//		if (ds.count == 2)
//			cout << "Y";
//		else
//			cout << "N";
//	}
//	else 
//		cout << "N";
//	return 0;
//}

//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//#include<numeric>
//using namespace std;
//int main()
//{
//	int n, m;
//	cin >> n >> m;
//	const int INF = 0x3f3f3f3f;
//	vector<vector<int>> dis(n+1,vector<int>(n+1,INF));
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		dis[t1][t2] = 1;
//		dis[t2][t1] = 1;
//	}
//	for (int k = 1; k <= n; k++)
//	{
//		for (int i = 1; i <= n; i++)
//		{
//			for (int j = 1; j <= n; j++)
//			{
//				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
//			}
//		}
//	}
//	for (int i = 1; i <= n; i++)
//	{
//		int count = 0;
//		for (int j = 1; j <= n; j++)
//		{
//			if (dis[i][j] <= 6)
//				count++;
//		}
//		double tmp = 100.0 * count / n;
//		printf("%d: %.2lf%%\n", i, tmp);
//	}
//	return 0;
//}
//
//#include<iostream>
//#include<vector>
//#include<string>
//#include<functional>
//#include<queue>
//#include<algorithm>
//#include<numeric>
//using namespace std;
//int main()
//{
//	int n, m;
//	cin >> n >> m;
//	const int INF = 0x3f3f3f3f;
//	vector<vector<int>> dis(n + 1, vector<int>(n + 1, INF));
//	for (int i = 0; i < m; i++)
//	{
//		int t1, t2;
//		cin >> t1 >> t2;
//		dis[t1][t2] = 1;
//		dis[t2][t1] = 1;
//	}
//	for (int k = 1; k <= n; k++)
//	{
//		for (int i = 1; i <= n; i++)
//		{
//			for (int j = 1; j <= n; j++)
//			{
//				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
//			}
//		}
//	}
//	for (int i = 1; i <= n; i++)
//	{
//		int count = 0;
//		for (int j = 1; j <= n; j++)
//		{
//			if (dis[i][j] <= 6)
//				count++;
//		}
//		double tmp = 100.0 * count / n;
//		printf("%d: %.2lf%%\n", i, tmp);
//	}
//	return 0;
//}

#include<iostream>
#include<vector>
#include<string>
#include<functional>
#include<queue>
#include<algorithm>
#include<numeric>
using namespace std;
 class Djset
{
public:
	vector<int> parent;
	int count;
	Djset(int n)
		:count(n)
	{
		parent.resize(n);
		iota(parent.begin(), parent.end(), 0);
	}
	int find(int x)
	{
		if (x != parent[x])
			parent[x] = find(parent[x]);
		return parent[x];
	}
	void merge(int x, int y)
	{
		int fx = find(x), fy = find(y);
		if (fx == fy)
			return;
		parent[fy] = fx;
		count--;
	}
};
 struct Edge
 {
	 int start, end, len;
 };
int main()
{
	int n, m;
	cin >> n >> m;
	vector<Edge> dis;
	Djset ds(n + 1);
	for (int i = 0; i < m; i++)
	{
		int t1, t2,t3;
		cin >> t1 >> t2 >> t3;
		dis.push_back({ t1,t2,t3 });
	}
	sort(dis.begin(), dis.end(), [&](const Edge& x, const Edge& y)
		{
			return x.len < y.len;
		});
	int ret = 0;
	for (int i = 0; i < m; i++)
	{
		if (ds.find(dis[i].start)!= ds.find( dis[i].end))
		{
			ret += dis[i].len;
			ds.merge(dis[i].start, dis[i].end);
		}
	}
	if (ds.count == 2)
		cout << ret;
	else
		cout << -1;
	return 0;
}